﻿using CSCore.Codecs.WAV;
using CSCore.SoundIn;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Media;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 声音采集
{
    public partial class MainForm : Form
    {
        private WasapiCapture capture = new WasapiLoopbackCapture();
        private WaveWriter writer;
        private SoundPlayer soundPlayer;
        private int second = 0;

        public MainForm()
        {
            InitializeComponent();
            capture.Initialize();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            if (writer != null || soundPlayer != null)
            {
                second++;
                label_Time.Invoke((MethodInvoker)(() =>
                {
                    label_Time.Text = TimeToString(second);
                }));
            }
        }

        /// <summary>
        /// 时间转字符串
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        private string TimeToString(int time)
        {
            int hour = 0, minute = 0, second = 0;
            hour = time / 3600;
            time %= 3600;
            minute = time / 60;
            time %= 60;
            second = time;

            StringBuilder sb = new StringBuilder();
            if (hour < 10)
            {
                sb.Append(0);
            }
            sb.Append(hour);
            sb.Append(':');
            if (minute < 10)
            {
                sb.Append(0);
            }
            sb.Append(minute);
            sb.Append(':');
            if (second < 10)
            {
                sb.Append(0);
            }
            sb.Append(second);
            return sb.ToString();
        }

        /// <summary>
        /// 采集声卡
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Start_Click(object sender, EventArgs e)
        {
            try
            {
                second = 0;

                if (writer != null)
                {
                    writer.Dispose();
                }

                writer = new WaveWriter("sound.wav", capture.WaveFormat);

                capture.DataAvailable += (s, ev) =>
                {
                    //save the recorded audio
                    writer.Write(ev.Data, ev.Offset, ev.ByteCount);
                };

                //start recording
                capture.Start();

                button_Start.Enabled = false;
                button_End.Enabled = true;
                button_Play.Enabled = false;
                button_Save.Enabled = false;

                timer.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 结束采集
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_End_Click(object sender, EventArgs e)
        {
            try
            {
                try
                {
                    capture.Stop();
                    if (writer != null)
                    {
                        writer.Dispose();
                        writer = null;
                    }
                }
                catch { }

                try
                {
                    if (soundPlayer != null)
                    {
                        soundPlayer.Stop();
                        soundPlayer.Dispose();
                        soundPlayer = null;
                    }
                }
                catch { }

                try
                {
                    if (timer.Enabled)
                    {
                        timer.Stop();
                    }
                }
                catch { }

                button_Play.Enabled = true;
                button_Save.Enabled = true;
                button_Start.Enabled = true;
                button_End.Enabled = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        ~MainForm()
        {
            try
            {
                capture.Dispose();
            }
            catch
            {

            }
        }

        /// <summary>
        /// 播放音频
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Play_Click(object sender, EventArgs e)
        {
            try
            {
                soundPlayer = new SoundPlayer("sound.wav");
                soundPlayer.Disposed += SoundPlayer_Disposed;

                Task.Run(() =>
                {
                    soundPlayer.Play();
                });

                button_Start.Enabled = false;
                button_Play.Enabled = false;
                button_Save.Enabled = false;
                button_End.Enabled = true;

                second = 0;
                if (!timer.Enabled)
                {
                    timer.Start();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void SoundPlayer_Disposed(object sender, EventArgs e)
        {
            button_Start.Enabled = true;
            button_Play.Enabled = true;
            button_Save.Enabled = true;
            button_End.Enabled = false;
            if (timer.Enabled)
            {
                timer.Stop();
            }
        }

        /// <summary>
        /// 保存音频
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Save_Click(object sender, EventArgs e)
        {
            try
            {
                SaveFileDialog dialog = new SaveFileDialog();
                dialog.Filter = "音频文件(wav)|*.wav";
                dialog.ShowDialog();

                if (dialog.FileName?.Length > 0)
                {
                    File.Copy("sound.wav", dialog.FileName);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}
